home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
macros
/
latex209
/
contrib
/
trees
/
pstrees
/
trees.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-28
|
7KB
|
373 lines
# include "align.h"
/* VAX VMS
# include <unixio>
*/
# include <stdio.h>
/* #define INC_COLUMNS */
/* externals from slurp */
extern char nextchar();
extern char peekchar();
extern int fetchline();
extern void writeline();
extern void skip_to();
extern FILE *outstream;
/* externals from words */
extern void readword();
extern void initstore();
/* types */
struct tnode {
word name;
int branch, term, tri;
struct tnode *mother, *daughters, *next;
char tag[10]; /* text of tag held in charstore */
};
typedef struct tnode treenode;
/* error stuff */
int sinned = FALSE; /* error has occurred in run */
int error = FALSE; /* error has occurred in current example */
FILE *error_file;
char error_name[50];
void goof(s)
char *s;
{
if (!sinned) {
error_file = fopen(error_name,"w");
sinned = TRUE;
}
fprintf(stderr,"%s at line %d\n",s,linecount());
fprintf(error_file,"%s at line %d\n",s,linecount);
error = TRUE;
}
char delmark = '|'; /* delimiter */
int tagcount; /* keeps track of tags */
/* strequ */
int strequ(s1,s2)
char *s1, *s2;
{
if (strcmp(s1,s2) == 0)
return(TRUE);
else
return(FALSE);
}
/* local node label & annotation-ending function */
static int endlabel(c)
char c;
{
if (eoln() || c == delmark) {
return(TRUE);
}
else
return(FALSE);
}
/* local command-word ending function */
static int endcom(c)
char c;
{
if (c == ' ' || c == delmark) {
return(TRUE);
}
else
return(FALSE);
}
/* adapted from K&R itoa */
void convert(n,s)
int n;
char s[];
{
int i;
i = 0;
do {
s[i++] = n % 26 + 'a';
} while ((n /= 26) > 0);
s[i] = '\0';
}
char grabchar()
{
char c;
c = nextchar();
if (c == '%') {
fetchline();
return(grabchar());
} else
return (c);
}
/* allocates nodespace, reads in info, etc. */
treenode *build_node()
{
int go;
treenode *node;
word holder;
char **pointer;
pointer = &(holder.loc);
node = (treenode *)malloc(sizeof(treenode));
readword(&node->name,&go,endlabel,grabchar,FALSE);
node->next = NULL;
node->daughters = NULL;
node->mother = NULL;
node->tri = FALSE;
node->term = TRUE;
node->tag[0]='\0';
while (go) {
readword(&holder,&go,endcom,nextchar,FALSE);
if (strequ(*pointer,"tri"))
node->tri=TRUE;
else
if (strequ(*pointer,"tag")) {
readword(&holder,&go,endcom,nextchar,FALSE);
strcpy(node->tag,*pointer);
}
}
if (node->tag[0] == '\0') {
node->tag[0] = 'Z';
convert(tagcount++,&(node->tag[1]));
}
return(node);
}
/* gets a node, assuming that the line the node is on is already read
in */
treenode *get_node()
{
int pos,dpos;
treenode *node;
advanceeoln_pos(&pos);
if (eoln()) {
goof("blank line in tree");
fetchline();
return(NULL);
}
node = build_node();
fetchline();
advanceeoln_pos(&dpos);
if (dpos > pos) {
get_daughters(node,dpos);
}
return(node);
}
get_daughters(node,dpos)
treenode *node; /* node of which daughters are being read */
int dpos; /* position where daughters are supposed to be */
{
int pos;
treenode *current;
current = get_node();
current->mother = node;
node->daughters = current;
node->term = FALSE;
while (currentpos() == dpos && !error) { /* as long as we're getting daughters */
current->next = get_node();
current = current->next;
current->mother = node;
}
}
void show_tree(node, ind)
treenode *node;
int ind;
{
int i;
if (node != NULL) {
for (i = 1; i<=ind; i++)
putc(' ', outstream);
fprintf(outstream,"%s\n",node->name.loc);
if (node->tri) printf("TRI\n");
printf("tag = %s\n",node->tag);
for (node = node->daughters; node !=NULL; node=node->next)
show_tree(node,ind+2);
}
}
void write_tree(node, ind)
treenode *node;
int ind;
{
int i;
treenode *mother;
if (node != NULL) {
mother = node;
for (i = 1; i<=ind; i++) /* print indentation */
putc(' ', outstream);
if (node->term) {
fprintf(outstream,"{\\tnode{%s}{%s}}",node->tag,node->name.loc);
}
else {
fprintf(outstream,"{\\ntnode{%s}{%s},\n",node->tag,node->name.loc);
for (node = node->daughters; node !=NULL; node=node->next)
write_tree(node,ind+2);
/*
for (i = 1; i<=ind; i++)
putc(' ', outstream);
*/
putc('}',outstream);
};
if (mother->next != NULL) fprintf(outstream,",\n");
/*
else fprintf(outstream,"%\n");
if (node->next != NULL && node->mother != NULL)
putc(',',outstream);
putc('\n',outstream);
*/
}
}
void draw_lines(node)
treenode *node;
{
int i;
char *m; /* mother & daughter tags */
treenode *mother; /* mother */
if (node != NULL) {
mother = node;
m = mother->tag;
for (node = mother->daughters; node !=NULL; node=node->next) {
if (node->tri)
fprintf(outstream,"\\nodetriangle{%s}{%s}%%\n",m,node->tag);
else
fprintf(outstream,"\\nodeconnect{%s}{%s}%%\n",m,node->tag);
}
for (node = mother->daughters; node !=NULL; node=node->next)
draw_lines(node);
}
}
void free_tree(node)
treenode *node;
{
if (node !=NULL) {
for (node = node->daughters; node !=NULL; node=node->next)
free_tree(node);
free(node);
node=NULL;
}
}
void tree()
{
treenode *node;
delmark = '|';
error = FALSE;
tagcount = 0;
init_store();
fetchline();
node=get_node();
if (!matchstr(".]") && !error)
goof("bad tree indentation");
if (error) {
fprintf(outstream,"\nBAD TREE\n");
error = FALSE;
}
else {
fprintf(outstream,"\\tree");
write_tree(node,0);
fprintf(outstream,"%%\n"),
draw_lines(node);
}
free_tree(node);
}
void extendfilename(name,extension,result)
/* chris: fix parameter declarations */
char name[];
char extension[];
char result[];
{
strcpy(result,name);
strcat(result,extension);
}
main(argc, argv)
int argc;
char *argv[];
{
char infile[200];
char outfile[200];
char c;
/* chris - let it run as filter */
if (argc < 2)
{
strcpy(infile, "stdin");
strcpy(error_name, "trees.err");
}
else
{
extendfilename(argv[1],".txp",infile);
extendfilename(argv[1],"_tx2.tex",outfile);
extendfilename(argv[1],".err",error_name);
}
/* VAX/VMS reading from logical `source', writing to logical `product'
open_source("source");
outstream = fopen("product","w");
*/
if (open_source(infile)) {
/* chris - letting it run as a filter still */
if (argc < 2)
outstream = stdout;
else
outstream = fopen(outfile,"w");
while (fetchline()) { /* as long as there's input */
if (nextchar() == '.') {
if ((c = nextchar()) == '[') {
tree();
}
#ifdef INC_COLUMNS
else
if (c == '<') {
columns();
}
#endif
}
else {
writeline();
}
}
} else printf("file `%s' not found\n",infile);
return(sinned);
}